package cn.virens.common.util.core.network;

import cn.virens.common.util.fun.ExFunction;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;

import java.util.function.Function;
import java.util.function.Supplier;

public class SessionUtil {

    /**
     * 获取SESSION值
     *
     * @param <T>     value的期望类型
     * @param session HttpSession对象
     * @param key     key值
     * @return value值
     */
    @SuppressWarnings("unchecked")
    public static <T> T getAttribute(HttpSession session, String key) {
        return session != null ? (T) session.getAttribute(key) : null;
    }

    /**
     * 获取SESSION值(如果不存在会根据supplier新建)
     *
     * @param <T>      value的期望类型
     * @param session  HttpSession对象
     * @param key      key值
     * @param supplier value供应者
     * @return value值
     */
    @SuppressWarnings("unchecked")
    public static <T> T getAttribute(HttpSession session, String key, Supplier<T> supplier) {
        T answer = session != null ? (T) session.getAttribute(key) : null;
        if (answer == null && supplier != null && key != null) {
            return setAttribute(session, key, supplier.get());
        } else {
            return answer;
        }
    }

    /**
     * 保存SESSION
     *
     * @param <T>     value值类型
     * @param session HttpSession对象
     * @param key     KEY值
     * @param value   value值
     * @return value值
     */
    public static <T> T setAttribute(HttpSession session, String key, T value) {
        if (session != null && key != null && value != null) {
            session.setAttribute(key, value);
        } else {
            return null;
        }

        return value;
    }

    /**
     * 删除SESSION中的指定值
     *
     * @param session HttpSession 对象
     * @param key     KEY值
     */
    public static void removeAttribute(HttpSession session, String key) {
        if (session != null && key != null) session.removeAttribute(key);
    }

    /**
     * 普通获取request中的session
     *
     * @param <R>     处理完成后的返回类型
     * @param request ServletRequest对象
     * @param create  是否创建新的session
     * @param fun     回调接口
     * @return 返回值
     */
    public static <R> R useSession(ServletRequest request, boolean create, Function<HttpSession, R> fun) {
        return request != null ? fun.apply(((HttpServletRequest) request).getSession(create)) : null;
    }

    /**
     * 普通获取request中的session(允许抛出异常)
     *
     * @param <R>     处理完成后的返回类型
     * @param request ServletRequest对象
     * @param create  是否创建新的session
     * @param fun     回调接口
     * @return 返回值
     * @throws Exception 处理异常
     */
    public static <R> R useSessionEx(ServletRequest request, boolean create, ExFunction<HttpSession, R> fun) throws Exception {
        return request != null ? fun.apply(((HttpServletRequest) request).getSession(create)) : null;
    }
}
